
#include "Material.h"

Material::Material(Vec3f ambientColor,Vec3f diffuseColr, Vec3f transparentColor, Vec3f reflectiveColor, 
				   float indexOfRefraction): m_ambientColor(ambientColor),
				   m_diffuseColor(diffuseColr),m_transparentColor(transparentColor),
				   m_reflectiveColor(reflectiveColor),m_indexOfRefraction(indexOfRefraction)
{
}

void Material::debugMessage() 
{
	printf("Material{\n\tindexOfRefraction=%.3f\n",m_indexOfRefraction);
	printf("\tdiffuseColor=("); m_diffuseColor.Write(); printf(")\n");
	printf("\ttransparentColor=("); m_transparentColor.Write(); printf(")\n");
	printf("\treflectiveColor=("); m_reflectiveColor.Write(); printf(")\n");
	printf("}//end Material\n\n");
}

PhongMaterial::PhongMaterial(Vec3f ambientColor,Vec3f diffuseColor, Vec3f specularColor, 
							 float exponent, Vec3f transparentColor,
							 Vec3f reflectiveColor, float indexOfRefraction)
:Material(ambientColor,diffuseColor,transparentColor,reflectiveColor,indexOfRefraction),
m_exponent(exponent),m_specularColor(specularColor)
{
}

Vec3f PhongMaterial::Shade(const Ray &ray, const Hit &hit, const Vec3f &dirToLight, 
					 const Vec3f &lightColor)const
{
	Vec3f rcolor,color;
	// all normallized
	const Vec3f &kd = m_diffuseColor;
	const Vec3f &ks = m_specularColor;
	const Vec3f &L = dirToLight;
	Vec3f N = hit.getNormal();
	Vec3f V = ray.getDirection()*-1.f;

	Vec3f H = (L+V)*0.5f;
	H.Normalize();
	
	float t1 = N.Dot3(L); float t2 = N.Dot3(H);
	if (t1<0.f) t1 = 0.f; if (t2<0.f) t2 = 0.f;

	color = kd*(t1/*N.Dot3(L)*/) + ks * pow(/*N.Dot3(H)*/t2,m_exponent);
	Vec3f::AddMul(rcolor,color,lightColor);
	return rcolor;
}